package jpf.nextsearch.base;

import java.io.IOException;
import java.util.Map;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import jpf.nextsearch.exception.InitializationException;

import org.apache.commons.lang.StringUtils;
import org.apache.log4j.Logger;
import org.springframework.validation.BindException;
import org.springframework.web.servlet.ModelAndView;
import org.springframework.web.servlet.mvc.SimpleFormController;

/**
 * @author <a href="mailto:jacek.pruszkowski@gmail.com">Jacek Pruszkowski</a>
 */
@SuppressWarnings("deprecation")
public class GenericFormController extends SimpleFormController implements
		GenericObjectInterface {
	
	public static final String EMBEDDED_PAGE_MODEL = "embeddedPage";

	private boolean loggingDebug;
	private boolean loggingError;
	private boolean loggingWarning;
	private boolean loggingInfo;
	private boolean redirectOnGeneralError = false;
	private String generalErrorRedirectUrl; 
	private GlobalConfiguration globalConfiguration;
	private Logger logger;
	private String templateView;

	public GenericFormController() {
		setLogger(Logger.getLogger(this.getClass()));
	}

	protected ModelAndView mergeModels(ModelAndView modelAndView,
			Map<String, Object> model) {
		modelAndView.getModel().putAll(model);
		return replaceViewToTemplate(modelAndView);
	}
	
	protected ModelAndView showForm(HttpServletRequest request, HttpServletResponse response, BindException errors) throws Exception {
		ModelAndView modelAndView = super.showForm(request, response, errors);
		return replaceViewToTemplate(modelAndView);
	}
	
	private ModelAndView replaceViewToTemplate(ModelAndView modelAndView) {
		if (!StringUtils.isBlank(getTemplateView())) {
			String view = modelAndView.getViewName();
			modelAndView.setViewName(getTemplateView());
			modelAndView.getModel().put(EMBEDDED_PAGE_MODEL, view);
		}
		return modelAndView;
	}
	
	protected ModelAndView handleGeneralError(HttpServletRequest request,
		HttpServletResponse response, Exception e) {
		
		if (isLoggingError()) {
			getLogger().error("Exception occoured", e);
		}
		if (isRedirectOnGeneralError()) {
			try {
				response.sendRedirect(getGeneralErrorRedirectUrl());
			} catch (IOException e1) {
				throw new RuntimeException(e1);
			}
			return null;
		}
		throw new RuntimeException(e);
	}

	/**
	 * @return the loggingDebug
	 */
	public boolean isLoggingDebug() {
		return loggingDebug;
	}

	/**
	 * @param loggingDebug
	 *            the loggingDebug to set
	 */
	public void setLoggingDebug(boolean loggingDebug) {
		this.loggingDebug = loggingDebug;
	}

	/**
	 * @return the loggingError
	 */
	public boolean isLoggingError() {
		return loggingError;
	}

	/**
	 * @param loggingError
	 *            the loggingError to set
	 */
	public void setLoggingError(boolean loggingError) {
		this.loggingError = loggingError;
	}

	/**
	 * @return the loggingWarning
	 */
	public boolean isLoggingWarning() {
		return loggingWarning;
	}

	/**
	 * @param loggingWarning
	 *            the loggingWarning to set
	 */
	public void setLoggingWarning(boolean loggingWarning) {
		this.loggingWarning = loggingWarning;
	}

	/**
	 * @return the loggingInfo
	 */
	public boolean isLoggingInfo() {
		return loggingInfo;
	}

	/**
	 * @param loggingInfo
	 *            the loggingInfo to set
	 */
	public void setLoggingInfo(boolean loggingInfo) {
		this.loggingInfo = loggingInfo;
	}

	/**
	 * @return the globalConfiguration
	 */
	public GlobalConfiguration getGlobalConfiguration() {
		return globalConfiguration;
	}

	/**
	 * @param globalConfiguration
	 *            the globalConfiguration to set
	 */
	public void setGlobalConfiguration(GlobalConfiguration globalConfiguration) {
		this.globalConfiguration = globalConfiguration;
	}

	/**
	 * Get the value of logger
	 * 
	 * @return the value of logger
	 */
	public Logger getLogger() {
		return logger;
	}

	/**
	 * Set the value of logger
	 * 
	 * @param logger
	 *            new value of logger
	 */
	public void setLogger(Logger logger) {
		this.logger = logger;
	}

	public void init() throws InitializationException {
		if (isLoggingInfo()) {
			getLogger()
					.info(
							"Initialising " + getClass().getName()
									+ " object instance");
		}
	}

	public void destroy() {
		if (isLoggingInfo()) {
			getLogger().info(
					"Destroying " + getClass().getName() + " object instance");
		}
	}

	public void setTemplateView(String templateView) {
		this.templateView = templateView;
	}

	public String getTemplateView() {
		return templateView;
	}

	public void setRedirectOnGeneralError(boolean redirectOnGeneralError) {
		this.redirectOnGeneralError = redirectOnGeneralError;
	}

	public boolean isRedirectOnGeneralError() {
		return redirectOnGeneralError;
	}

	public void setGeneralErrorRedirectUrl(String generalErrorRedirectUrl) {
		this.generalErrorRedirectUrl = generalErrorRedirectUrl;
	}

	public String getGeneralErrorRedirectUrl() {
		return generalErrorRedirectUrl;
	}

}
